package com.hollowlatte.manage.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hollowlatte.common.exceptionhandler.CustomException;
import com.hollowlatte.manage.entity.Perms;
import com.hollowlatte.manage.entity.Role;
import com.hollowlatte.manage.entity.RolePerms;
import com.hollowlatte.manage.entity.vo.PermsVO;
import com.hollowlatte.manage.entity.vo.RoleVO;
import com.hollowlatte.manage.mapper.PermsMapper;
import com.hollowlatte.manage.mapper.RoleMapper;
import com.hollowlatte.manage.mapper.RolePermsMapper;
import com.hollowlatte.manage.service.RoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Hollow Latte
 * @since 2021-04-27
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    private final RoleMapper roleMapper;

    private final PermsMapper permsMapper;

    private final RolePermsMapper rolePermsMapper;

    public RoleServiceImpl(RoleMapper roleMapper, PermsMapper permsMapper, RolePermsMapper rolePermsMapper) {
        this.roleMapper = roleMapper;
        this.permsMapper = permsMapper;
        this.rolePermsMapper = rolePermsMapper;
    }


    @Override
    public boolean assignPermsForRole(Long roleId, Long permsId) {
        Role role = roleMapper.selectById(roleId);
        Perms perms = permsMapper.selectById(permsId);
        if (ObjectUtils.isEmpty(role)) {
            throw new CustomException("A0400", "角色不存在");
        }
        if (ObjectUtils.isEmpty(perms)) {
            throw new CustomException("A0400", "权限不存在");
        }

        RolePerms rolePerms = new RolePerms();
        rolePerms.setRoleId(roleId);
        rolePerms.setPermsId(permsId);


        if (!ObjectUtils.isEmpty(rolePermsMapper.selectByRoleIdAndPermsId(roleId, permsId))) {
            throw new CustomException("A0400", "重复添加已拥有权限");
        }
        int affect = rolePermsMapper.insert(rolePerms);

        return affect != 0;
    }

    @Override
    public List<Perms> listPermsById(Long id) {
        return roleMapper.selectPermsById(id);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeRole(Long roleId) {
        int affect1 = roleMapper.deleteById(roleId);

        int affect2 = rolePermsMapper.deleteByRoleId(roleId);

        return affect1 != 0 && affect2 != 0;
    }


    @Override
    public boolean removePermsOfRole(Long roleId, Long permsId) {
        int affect = rolePermsMapper.deleteByRoleIdAndPermsId(roleId, permsId);
        return affect != 0;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updatePermsForRole(Long roleId, List<Long> newPermsIdList) {
        Role role = roleMapper.selectById(roleId);
        if (ObjectUtils.isEmpty(role)) {
            throw new CustomException("A0400", "角色不存在");
        }
        for (Long permsId : newPermsIdList) {
            if (ObjectUtils.isEmpty(permsMapper.selectById(permsId))) {
                throw new CustomException("A0400", "权限不存在");
            }
        }

        rolePermsMapper.deleteByRoleId(roleId);

        for (Long permsId : newPermsIdList) {
            RolePerms rolePerms = new RolePerms();
            rolePerms.setRoleId(roleId);
            rolePerms.setPermsId(permsId);
            rolePermsMapper.insert(rolePerms);
        }
        return true;
    }


    @Override
    public List<RoleVO> convertRoleToRoleVO(List<Role> roleList) {
        List<RoleVO> roleVOList = new ArrayList<>();
        for (Role role : roleList) {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);

            List<PermsVO> permsVOList = roleMapper.selectPermsById(role.getId())
                    .stream()
                    .map(perms -> {
                        PermsVO permsVO = new PermsVO();
                        BeanUtils.copyProperties(perms, permsVO);
                        return permsVO;
                    })
                    .collect(Collectors.toList());

            roleVO.setPermsList(permsVOList);
            roleVOList.add(roleVO);
        }
        return roleVOList;
    }
}
